<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>iterator</title>
</head>
<body>

<!--
  iterator是一种接口机制,为各种不同的数据结构提供统一的访问机制
  Iterator接口主要供for...of消费。
  创建一个指针对象(遍历器对象)指向数据结构的起始位置
  第一次调用next方法 指针自动指向数据结构的第一个成员
  每次调用next方法返回的是一个包含value和done的对象
  当数据结构部署了Symbol.iterator接口 该数据可以用for of 遍历
  
  //Sysmbol.iterator属性指向对象的默认遍历器方法
  1.Array
  2.arguments
  3.set
  4.map
  5.String
  
-->
<script>
  //模拟指针对象(遍历器对象)
  function myIterator(arr){
    let nextIndex = 0;//记录指针的位置
    return {//遍历器对象
      next: function () {
        return nextIndex < arr.length?{value: arr[nextIndex++], done: false}:{value:undefined,done:true}
      }
    }
  }
  
  //准备一个数据
  let arr = [1,4,67,'abc'];
  let iteratorObj = myIterator(arr);
  console.log(iteratorObj.next());;
  console.log(iteratorObj.next());;
  console.log(iteratorObj.next());;
  console.log(iteratorObj.next());;
  console.log(iteratorObj.next());;
  console.log(iteratorObj.next());;
  
  //ES6已经将Iterator接口部署到指定的数据类型上了. 可以用for...of遍历
  //这些数据类型分别是: 数组,字符串,arguments,,set,map
  for(let i of arr){
    console.log(i);
  }
  
  let str = 'abcdefg';
  for(let i of str){
    console.log(i);
  }
  
  //arguments是一个伪数组 不能使用forEach调用
  function func(){
    for(let i of arguments){
      console.log(i);
    }
  }
  func(1,4,5,'def');
  
  //怎么把这个接口部署到某个数据结构上呢
  //对象的Symbol.iterator属性,指向该对象的默认遍历器方法
  let targetData = {
    [Symbol.iterator]: function(){
      let nextIndex = 0;//记录指针的位置
      return {//遍历器对象
        next: function () {
          return nextIndex < this.length?{value: this[nextIndex++], done: false}:{value:undefined,done:true}
        }
      }
    }
  }
  
  //使用三点运算符,解构赋值,默认去调用iterator接口
  let arr2 = [1,6];
  let arr3 = [2,3,4,5];
  arr2 = [1,...arr3,6];
  console.log(arr2);
  
  let [a,b] = arr2;
  console.log(a,b);
</script>
</body>
</html>